package com.benyanyi.okhttp.type;

import android.content.Context;

import com.benyanyi.okhttp.call.HttpCall;
import com.benyanyi.okhttp.call.RequestConfig;
import com.benyanyi.okhttp.download.DownloadCall;
import com.benyanyi.okhttp.download.DownloadConfig;
import com.benyanyi.okhttp.util.FormatUtil;
import com.benyanyi.okhttp.util.OkHttpLog;
import com.google.gson.Gson;

import java.io.File;
import java.util.List;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * @author YanYi
 * @date 2019-08-12 16:02
 * @email ben@yanyi.red
 * @overview
 */
public class HttpRequest implements RequestType {

    private Context context;
    private boolean isCache;
    private String url;
    private String mCacheName;
    private Request request;

    public HttpRequest(Context context, String url, boolean isCache) {
        this.context = context;
        this.url = url;
        this.isCache = isCache;
        this.mCacheName = url;
    }

    @Override
    public RequestConfig getText(Map<Object, Object> map) {
        StringBuilder str = new StringBuilder(url);
        if (FormatUtil.isMapNotEmpty(map)) {
            mCacheName = mCacheName + map.toString();
            str.append("?");
            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                str.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
            str = new StringBuilder(str.substring(0, str.length() - 1));
        }
        OkHttpLog.d(str);
        request = new Request.Builder()
                .url(str.toString())
                .get()
                .build();
        return send();
    }

    @Override
    public RequestConfig postText(Map<Object, Object> headerMap, Map<Object, Object> bodyMap) {
        FormBody.Builder builder = new FormBody.Builder();
        if (FormatUtil.isMapNotEmpty(bodyMap)) {
            mCacheName = mCacheName + bodyMap.toString();
            for (Map.Entry<Object, Object> entry : bodyMap.entrySet()) {
                builder.add(entry.getKey().toString(), entry.getValue().toString());
            }
        }
        FormBody build = builder.build();
        Request.Builder builder1 = new Request.Builder();
        if (FormatUtil.isMapNotEmpty(headerMap)) {
            for (Map.Entry<Object, Object> entry : headerMap.entrySet()) {
                builder1.addHeader(entry.getKey().toString(), entry.getValue().toString());
            }
        }
        request = builder1.url(url)
                .post(build)
                .build();
        return send();
    }

    @Override
    public RequestConfig postJson(Map<Object, Object> map) {
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        if (FormatUtil.isMapNotEmpty(map)) {
            mCacheName = mCacheName + map.toString();
            RequestBody requestBody = RequestBody.create(mediaType, new Gson().toJson(map));
            request = new Request.Builder()
                    .url(url)
                    .addHeader("content-type", "application/json")
                    .post(requestBody)
                    .build();
        } else {
            request = new Request.Builder()
                    .url(url)
                    .post(new FormBody.Builder().build())
                    .build();
        }
        return send();
    }

    @Override
    public RequestConfig postJson(String string) {
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        if (FormatUtil.isNotEmpty(string)) {
            mCacheName = mCacheName + string;
            RequestBody requestBody = RequestBody.create(mediaType, string);
            request = new Request.Builder()
                    .url(url)
                    .addHeader("content-type", "application/json")
                    .post(requestBody)
                    .build();
        } else {
            request = new Request.Builder()
                    .url(url)
                    .post(new FormBody.Builder().build())
                    .build();
        }
        return send();
    }

    @Override
    public RequestConfig xml(String xml) {
        String str = xml;
        MediaType mediaType = MediaType.parse("text/xml; charset=UTF-8");
        if (FormatUtil.isNotEmpty(str)) {
            mCacheName = mCacheName + str;
        } else {
            str = "";
        }
        request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(mediaType, str))
                .build();
        return send();
    }

    @Override
    public RequestConfig file(Map<Object, Object> map) {
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);
        if (FormatUtil.isMapNotEmpty(map)) {
            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                File file = new File(entry.getValue().toString());
//                int indexOf = entry.getValue().toString().indexOf("/");
//                RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
                RequestBody requestBody = RequestBody.create(file, MediaType.parse("multipart/form-data"));
//                String fileName = entry.getKey().toString().substring(indexOf + 1);
                String fileName = entry.getKey().toString();
                builder.addFormDataPart(entry.getKey().toString(), fileName, requestBody);
            }
        }
        MultipartBody multipartBody = builder.build();
        request = new Request.Builder()
                .url(url)
                .post(multipartBody)
                .build();
        return send(true);
    }

    @Override
    public RequestConfig file(String... filePaths) {
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);
        if (filePaths != null && filePaths.length > 0) {
            for (String str : filePaths) {
                File file = new File(str);
//                int indexOf = entry.getValue().toString().indexOf("/");
//                RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
                RequestBody requestBody = RequestBody.create(file, MediaType.parse("multipart/form-data"));
//                String fileName = entry.getKey().toString().substring(indexOf + 1);
                builder.addFormDataPart("file", file.getName(), requestBody);
            }
        }
        MultipartBody multipartBody = builder.build();
        request = new Request.Builder()
                .url(url)
                .post(multipartBody)
                .build();
        return send(true);
    }

    @Override
    public RequestConfig file(List<String> filePaths) {
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);
        if (filePaths != null && filePaths.size() > 0) {
            for (String str : filePaths) {
                File file = new File(str);
//                int indexOf = entry.getValue().toString().indexOf("/");
//                RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
                RequestBody requestBody = RequestBody.create(file, MediaType.parse("multipart/form-data"));
//                String fileName = entry.getKey().toString().substring(indexOf + 1);
                builder.addFormDataPart("file", file.getName(), requestBody);
            }
        }
        MultipartBody multipartBody = builder.build();
        request = new Request.Builder()
                .url(url)
                .post(multipartBody)
                .build();
        return send(true);
    }

    @Override
    public DownloadConfig download() {
        return new DownloadCall.Builder().setContext(context).setUrl(url).setCover(false).setSuffix("").builder();
    }

    @Override
    public DownloadConfig download(boolean isCover) {
        return new DownloadCall.Builder().setContext(context).setUrl(url).setCover(isCover).setSuffix("").builder();
    }

    @Override
    public DownloadConfig download(String suffix) {
        return new DownloadCall.Builder().setContext(context).setUrl(url).setCover(false).setSuffix(suffix).builder();
    }

    @Override
    public DownloadConfig download(boolean isCover, String suffix) {
        return new DownloadCall.Builder().setContext(context).setUrl(url).setCover(isCover).setSuffix(suffix).builder();
    }

    private RequestConfig send() {
        return send(false);
    }

    private RequestConfig send(boolean isFile) {
        return new HttpCall.Builder()
                .setCache(isCache)
                .setCacheUrl(mCacheName)
                .setContext(context)
                .setHttpClient(Client.getClient(context, isCache, isFile))
                .setRequest(request)
                .builder();
    }

}
